package validator

import (
	"fmt"
	"reflect"
)

type In[T RangeTypes] struct {
	getValue func(reflect.Value) T
	array    []T
}

func NewInValidator[T RangeTypes](array []T, getValue func(reflect.Value) T) *In[T] {
	return &In[T]{
		getValue: getValue,
		array:    array,
	}
}
func (in *In[T]) String() string {
	var items string
	for n, v := range in.array {
		if n == 0 {
			items = fmt.Sprintf("%v", v)
		} else {
			items = fmt.Sprintf("%s,%v", items, v)
		}
	}
	return fmt.Sprintf("[%s]", items)
}

func (in *In[T]) IsValidate(field string, data reflect.Value) error {
	var v = in.getValue(data)
	for _, item := range in.array {
		if v == item {
			return nil
		}
	}
	return fmt.Errorf("field [%s]'s must be one of %v", field, in.array)
}

type NotIn[T RangeTypes] struct {
	getValue func(reflect.Value) T
	array    []T
}

func NewNotInValidator[T RangeTypes](array []T, getValue func(reflect.Value) T) *NotIn[T] {
	return &NotIn[T]{
		getValue: getValue,
		array:    array,
	}
}

func (ni *NotIn[T]) String() string {
	var items string
	for n, v := range ni.array {
		if n == 0 {
			items = fmt.Sprintf("%v", v)
		} else {
			items = fmt.Sprintf("%s,%v", items, v)
		}
	}
	return fmt.Sprintf("(%s)", items)
}
func (ni *NotIn[T]) IsValidate(field string, data reflect.Value) error {
	var v = ni.getValue(data)
	for _, item := range ni.array {
		if v == item {
			return nil
		}
	}
	return fmt.Errorf("field [%s]'s must not be one of %v", field, ni.array)
}
